/*
 * Protocolo_NIPC.c
 *
 *  Created on: 22/10/2011
 *      Author: utn_so
 */

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include "Protocolo_NIPC.h"

int abre_SocketServidor(int puerto, const char *direccion){
	struct sockaddr_in server_address;
	unsigned int server_len;
	int Descriptor;
	Descriptor = socket (AF_INET, SOCK_STREAM, 0);
	if(Descriptor == -1)
		return Descriptor;
	/*
	* Se rellenan los campos de la estructura Direccion, necesaria
	* para la llamada a la funcion bind()
	*/
	int32_t optval;
	optval = 1;
	setsockopt(Descriptor, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval));
	memset(&server_address, 0, sizeof(server_address));
	server_address.sin_family = AF_INET;
	server_address.sin_addr.s_addr = inet_addr(direccion) ;
	server_address.sin_port = puerto;
	server_len = sizeof(server_address);
	if(bind(Descriptor, (struct sockaddr *) &server_address, server_len) != -1){
		listen(Descriptor, 1);
		printf("listen\n");
		} else {
		close(Descriptor);
	}
	 /* Se devuelve el descriptor del socket servidor
	 */
	return Descriptor;
}

int acepta_Socket(int server_sockfd) {
	unsigned int client_len, client_sockfd;
	struct sockaddr_in client_address;
	client_len = sizeof(client_address);
	client_sockfd = accept(server_sockfd, (struct sockaddr *) &client_address, &client_len);
	return client_sockfd;
}

int abre_SocketCliente(int puerto,const char *direccion){
	int result, sockfd, len;
	struct sockaddr_in address;
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	memset(&address, 0, sizeof(address));
	address.sin_family = AF_INET;
	address.sin_addr.s_addr = inet_addr(direccion);
	address.sin_port = puerto;
	len = sizeof(address);
	result = connect(sockfd, (struct sockaddr *)&address, len);
	return result;
}

int handshakePPD(int socket, int identificador_disco) {
	paquete *NIPC;
	int* id_disk; id_disk = (int*)malloc(sizeof(int));
	*id_disk = identificador_disco;
	NIPC = (paquete*) malloc (515);
	NIPC->type = 0;
	NIPC->payload_Length = sizeof(int);
	strcpy(NIPC->payload, (char*) id_disk);
	send(socket, NIPC, 515, 0);
	printf("Se envio todo muy lindo\n");
	paquete *recibirNIPC;
	recibirNIPC = (paquete*) malloc (sizeof(paquete));
	int length_recibido,resultado_operacion;
	length_recibido = recv(socket, recibirNIPC,515, 0);
	printf("Recibi todo muy lindo\n");
	if (recibirNIPC->type == 0 && recibirNIPC->payload_Length == 0) {
		resultado_operacion = 1;
	} else {
		if(recibirNIPC->type == 0 && recibirNIPC->payload_Length != 0){
		resultado_operacion = 0;
		printf("%s",(char*)recibirNIPC->payload);}
	}
	return resultado_operacion;
}
/*
paquete PPD_RECIBEPEDIDO_RAID (int socket, paquete *NIPC){
	recv(socket, &NIPC, 515,0);
	return *NIPC; // PARA QUE SEPA QUE TIPO DE PEDIDO ME HIZO
}

paquete PPD_MANDAPEDIDO_RAID (int socket, paquete *NIPC){
	send(socket, NIPC, 515,0);
	return *NIPC; // para que luego el raid se lo mande al FS.
}*/

paquete *handshakePRAID(int socket) {
	paquete *NIPC;
	NIPC = (paquete*) malloc(sizeof(paquete));
	recv(socket, NIPC, sizeof(paquete), MSG_WAITALL); //todo MSG_WAITALL
	return NIPC;
}

/*int handshakeFS(int socket, paquete *NIPC){
	send(socket, NIPC,515, 0);
	int resultadoHS;
	paquete *recibirNIPC;
	resultadoHS = recibirNIPC = (paquete*) malloc (515);
	recv(socket, recibirNIPC, 515, 0);
	return resultadoHS;
}*/

int handshakeFS(int socket){
	paquete *NIPC=malloc(sizeof(paquete));
	NIPC->type=handshake;
	NIPC->payload_Length=0;
	strcpy(NIPC->payload, "");
	int algo;
	algo = send(socket, NIPC, sizeof(paquete), 0);
	NIPC->type=leer; //para probar que recivimos bien
	NIPC->payload_Length=0;
	printf("envio handshake\n");
	recv(socket, NIPC, sizeof(paquete), MSG_WAITALL);
	if(NIPC->type==handshake && NIPC->payload_Length==0){
		free(NIPC);
		printf("recibio bien\n");
		return 0;
	}
	else{
		free(NIPC);
		perror("handshake incorrecto");
		return -1;
	}
}

/*int enviarPaquete(int socket, paquete NIPC){
	int bytesPorEnviar=0, bytesEnviados=0;

	bytesPorEnviar = NIPC.payload_Length + sizeof(NIPC.nroSector) + sizeof(NIPC.payload_Length) + sizeof(char);

}*/



